﻿#region Imports
using System;
using System.Collections.Generic;
using System.Linq;
using BulkRenamer.Util.Enums;
using Microsoft.VisualBasic;
#endregion

namespace BulkRenamer.Util.Extensions
{
    /// <summary>
    /// Extension methods for misc. func.
    /// </summary>
    /// <seealso cref="http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class" />
    /// <seealso cref="http://stackoverflow.com/questions/866921/static-extension-methods" />
    /// <seealso cref="http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx" />
    public static class MiscExtensions
    {
        public static object GetKey(this Dictionary<string, object> dict, string key, bool throwException = false)
        {
            if (dict.ContainsKey(key))
                return dict[key];
            else { if (throwException) return dict[key]; else return null; }
        }

        public static string GetFolderPath(this Environment.SpecialFolder spclFolder)
        {
            return Environment.GetFolderPath(spclFolder);
        }

        /// <summary>
        /// Returns a string containing a specified number of characters from the left/right side of a string
        /// </summary>
        /// <param name="value">Text to evaluate</param>
        /// <param name="length">No. of characters to return from left/right
        /// <para>length = 0 returns a zero-length string (quot;quot;)</para>
        /// <para>length greater than or equal to the no. of characters returns the entire string</para></param>
        /// <param name="trimDirection">Trim from direction</param>
        /// <returns></returns>
        public static string TrimAndTake(this string value, int length, eTrimDirection trimDirection)
        {
            if (value.IsNullOrEmpty()) value = "";
            if (length < 0) throw new ArgumentException("Length cannot be negative.");
            else if (length > value.Length) throw new ArgumentException("Specified trim length is greater than string.");

            switch (trimDirection)
            {
                case eTrimDirection.Right:
                    return Strings.Right(value, length);
                case eTrimDirection.Left:
                default:
                    return Strings.Left(value, length);
            }
        }

        /// <summary>
        /// Returns a string leaving out a specified number of characters from the left/right side of a string
        /// <para>(equivalent to TrimStart/TrimEnd)</para>
        /// </summary>
        /// <param name="value">Text to evaluate</param>
        /// <param name="length">No. of characters to leave out from left/right
        /// <param name="trimDirection">Trim from direction</param>
        /// <returns></returns>
        public static string TrimAndLeave(this string value, int length, eTrimDirection trimDirection)
        {
            if (value.IsNullOrEmpty()) value = "";
            if (length < 0) throw new ArgumentException("Length cannot be negative.");
            else if (length > value.Length) throw new ArgumentException("Specified trim length is greater than string.");

            switch (trimDirection)
            {
                case eTrimDirection.Left:
                    trimDirection = eTrimDirection.Right;
                    break;
                case eTrimDirection.Right:
                    trimDirection = eTrimDirection.Left;
                    break;
                default:
                    break;
            }

            return value.TrimAndTake(value.Length - length, trimDirection);
        }

        /// <summary>
        /// Removes text from specified string
        /// </summary>
        /// <param name="value">Text to be operated on</param>
        /// <param name="remove">Array of text to be removed</param>
        /// <returns>Text after removing specified part</returns>
        public static string RemoveText(this string value, params string[] remove)
        {
            foreach (string txt in remove) value = value.Replace(txt, "");
            return value;
        }

        /// <summary>
        /// Adds '*.' characters to file extension
        /// </summary>
        /// <param name="value">String to format</param>
        /// <returns></returns>
        public static string AddExtnChars(this string value)
        {
            return "*." + value.RemoveText(".", "*"); // RKD : (".*".ToCharArray().Select(val => val.ToString()).ToArray());
        }

        /// <summary>
        /// Removes '*.' characters from file extension
        /// </summary>
        /// <param name="value">String to format</param>
        /// <returns></returns>
        public static string RemoveExtnChars(this string value)
        {
            return value.RemoveText(".", "*");
        }

        /// <summary>
        /// Indicates whether the specified string is null or an System.String.Empty string.
        /// </summary>
        /// <param name="value">String to evaluate</param>
        /// <returns>true if the value parameter is null or an empty string (""); otherwise, false</returns>
        /// <exception cref="T:System.ArgumentNullException">Value is null</exception>
        public static bool IsNullOrEmpty(this string value)
        {
            return String.IsNullOrEmpty(value);
        }

        public static byte[] ConvertToByteArray(this string value, int length)
        {
            return Utilities.ConvertStringToByteArray(value, length);
        }

        public static string TrimEmptyChars(this string value)
        {
            return Utilities.ConvertByteArrayToString(value.ConvertToByteArray(value.Length), true);
        }
    }
}
